package mx.com.zl0.scheduler.tasks;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.TimerTask;

import mx.com.zl0.scheduler.iterator.ScheduleIterator;
import mx.com.zl0.util.Util;

public abstract class SchedulerTask implements Runnable {
    public  static final int VIRGIN = 0;
    public  static final int SCHEDULED = 1;
    public  static final int CANCELLED = 2;
    private static final Map<Integer, String> states;

    public  final Object lock = new Object();
	private final ScheduleIterator scheduleIterator;
	private final String id;
	private final boolean runAtInit;

	private int state = VIRGIN;
    private TimerTask timerTask;
    private Date initTime;

    static {
    	states = new HashMap<Integer, String>(3);
    	states.put(VIRGIN, "Nuevo");
    	states.put(SCHEDULED, "Programado");
    	states.put(CANCELLED, "Cancelado");
    }

    protected SchedulerTask(ScheduleIterator scheduleIterator, String id, boolean runAtInit) {
    	this.scheduleIterator = scheduleIterator;
    	this.id = id;
    	this.initTime = runAtInit ? new Date(): null;
    	this.runAtInit = runAtInit;    	
    }

    public abstract void run();
    
    public ScheduleIterator getScheduleIterator() {
    	return scheduleIterator;
    }

    public boolean cancel() {
        synchronized(lock) {
            if (timerTask != null) {
                timerTask.cancel();
            }
            boolean result = state == SCHEDULED;
            state = CANCELLED;
            initTime = null;
            return result;
        }
    }

    public long getScheduledExecutionTime() {
        synchronized(lock) {
            return timerTask == null ? 0 : timerTask.scheduledExecutionTime();
        }
    }
    
    public String getExecutionTime() {    	
    	return this.initTime == null ? "-" : Util.tiempoEjecucion(initTime);
    }
    
	public String getId() {
		return id;
	}

	public String getStringState() {
		return states.get(state);
	}
	
	public int getState() {
		return state;
	}
	
	public boolean isRunning() {
		return this.state == SCHEDULED;
	}

	public boolean isRunAtInit() {
		return runAtInit;
	}

	public Date getInitTime() {
		return initTime;
	}

	public void setInitTime(Date initTime) {
		this.initTime = initTime;
	}

	public TimerTask getTimerTask() {
		return timerTask;
	}

	public void setTimerTask(TimerTask timerTask) {
		this.timerTask = timerTask;
	}

	public void setState(int state) {
		this.state = state;
	}

	public SchedulerTask execute() {
		state = VIRGIN;
		initTime = new Date();
		scheduleIterator.restart();
		return this;
	}
}